package com.ebeitech.doorapp.util;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.PermissionChecker;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;

import com.ebeitech.doorapp.http.HttpListener;
import com.ebeitech.doorapp.http.service.HttpCommonServiceRx;
import com.ebeitech.doorapp.R;
import com.ebeitech.doorapp.application.EbeiApplication;
import com.ebeitech.doorapp.constants.ActionConstants;
import com.ebeitech.doorapp.constants.CommonConstants;
import com.ebeitech.doorapp.domain.dao.UserDao;
import com.ebeitech.doorapp.http.EbeiErrorCode;
import com.ebeitech.doorapp.http.HttpService;
import com.ebeitech.doorapp.http.model.VersionModel;
import com.ebeitech.doorapp.push.xiaomi.PushUtils;
import com.ebeitech.doorapp.qqim.util.QQIMUtil;
import com.ebeitech.doorapp.util.compat.FragmentCompat;
import com.ebeitech.doorapp.util.compat.PackageManagerWrapper;
import com.ebeitech.doorapp.view.VersionService;
import com.ebeitech.doorapp.view.homepage.LoginActivity;
import com.ebeitech.library.constant.SPConstants;
import com.ebeitech.library.ui.dialog.CommonAlertDialogFragment;
import com.ebeitech.library.util.CommonUtil;
import com.ebeitech.library.util.Log;
import com.ebeitech.library.util.SPManager;
import com.ebeitech.library.util.StringUtil;
import com.ebeitech.library.util.VersionUtil;
import com.ebeitech.library.util.ViewUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import okhttp3.ResponseBody;
import retrofit2.Call;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by alice on 2017/11/7.
 */
public class PublicUtil {

	public static void doLogout(final Context context) {
		Observable.create(new Observable.OnSubscribe<Boolean>() {

			@Override
			public void call(Subscriber<? super Boolean> subscriber) {
				UserDao.getInstance().setUserLogout(EbeiApplication.getUserAccount());
				QQIMUtil.getInstance().doLogout();
				PushUtils.sendMyStateUrl(context, SPConstants.LOGOUT_STATE);
				SPManager.getInstance(context).put(CommonConstants.IS_LOGIN_OFFLINE, true);

				subscriber.onNext(true);
			}
		}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Boolean>() {
			@Override
			public void onCompleted() {

			}

			@Override
			public void onError(Throwable e) {

			}

			@Override
			public void onNext(Boolean aBoolean) {
				EbeiApplication.exit();
				Intent intent = new Intent(context, LoginActivity.class);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				intent.putExtra("isLogout",true);
				EbeiApplication.getContext().startActivity(intent);
			}
		});
	}

	public static void showCheckVersionDialog(final Context context, final String downloadUrl, String versionName, String updateContent) {
		final FragmentManager fm;
		if (context instanceof FragmentActivity) {
			fm = ((FragmentActivity) context).getSupportFragmentManager();
		} else {
			fm = null;
		}
		if (fm == null) {
			return;
		}
		CommonAlertDialogFragment dialogFragment = ViewUtil.getAlertDialog(context, context.getString(R.string.ebei_new_version_x, versionName),
				updateContent, new CommonAlertDialogFragment.OnBtnClickListener() {
			@Override
			public void onClick(View v, CommonAlertDialogFragment dialog) {
				ViewUtil.dismissDialog(dialog);

				Intent intent = new Intent(context, VersionService.class);
				intent.putExtra("url", downloadUrl);
				context.startService(intent);
			}
		}, new CommonAlertDialogFragment.OnBtnClickListener() {
			@Override
			public void onClick(View v, CommonAlertDialogFragment dialog) {
				ViewUtil.dismissDialog(dialog);
			}
		}, context.getString(R.string.ebei_download_right_now), context.getString(R.string.ebei_download_later));

		dialogFragment.setMessageGravity(Gravity.LEFT);
		dialogFragment.show(fm, "CheckVersionDialog");
	}

	/**
	 * 检查版本更新
	 */
	public static void checkVersion(final Context context) {
		// Alice modify
		if (true) {
			return;
		}
		String versionName = VersionUtil.getVersionName(context);
		Map<String, String> params = new HashMap<String, String>();
		params.put("platform", "1");
		params.put("version", versionName);
		HttpService mHttpService = HttpService.getInstance();
		HttpCommonServiceRx mHttpAuctionServiceRx = mHttpService.getRxGsonRetrofit().create(HttpCommonServiceRx.class);
		final Call<ResponseBody> mCall = mHttpAuctionServiceRx.checkVersion(params);
		mHttpService.executeHttp(context, mCall, new HttpListener<VersionModel>() {
			@Override
			public void onStart() {

			}

			@Override
			public void onError(EbeiErrorCode errorCode) {

			}

			@Override
			public void onSuccess(VersionModel baseModel) {
				if (baseModel.getData().isHasNewVersion())
				{
					PublicUtil.showCheckVersionDialog(context, baseModel.getData().get_$1().getUrl(), baseModel.getData().get_$1().getVersion(), baseModel.getData().get_$1().getUpdateDesc());
				}
			}
		}, VersionModel.class, false);

	}

	/**
	 * 获取存储的根目录
	 * @return
	 */
	public static String getCordovaFilePrefix(Context context) {
		return "ebeifile://";
	}

	/**
	 * 获取某个应用的文件夹
	 * @param context
	 * @return
	 */
	public static String getAppFile(Context context) {
		String appId = SPManager.getInstance(context).get(SPConstants.APP_ID, "");
		String fileName = "Doc";
		if (!StringUtil.isStringNullOrEmpty(appId)) {
			fileName += File.separator + appId;
		}
		return CommonUtil.getFile(context, fileName);
	}

	/**
	 * 设置旋转角度
	 *
	 * @param view
	 * @param rotation
	 */
	public static void setRotation(View view, float rotation) {
		if (Build.VERSION.SDK_INT < 11) {
			RotateAnimation animation = new RotateAnimation(0, rotation,
					Animation.RELATIVE_TO_SELF, 0.5f,
					Animation.RELATIVE_TO_SELF, 0.5f);
			animation.setDuration(100);
			animation.setFillAfter(true);
			view.startAnimation(animation);
		} else {
			view.setRotation(rotation);
		}
	}

	/**
	 * 防止不停地点击 （小于3秒钟）
	 * @param v
	 * @return
	 */
	public static boolean shouldCommit(View v) {
		String lastClick = (String) v.getTag();
		if (StringUtil.isStringNullOrEmpty(lastClick)) {
			lastClick = "0";
		}
		long millis = Long.parseLong(lastClick);
		long now = System.currentTimeMillis();
		v.setTag(String.valueOf(System.currentTimeMillis()));
		return (Math.abs(now - millis) >= 3 * 1000);
	}

	public static ArrayList<String> getMediaPathsFromIntent(Intent intent) {
		ArrayList<String> mediaFiles = new ArrayList<String>();
		int fileType = intent.getIntExtra(SPConstants.FILE_TYPE, 0);
		File mediaFile = null;
		switch (fileType) {
			case SPConstants.REQUEST_CAMERA: {
				ArrayList<String> photos = intent.getStringArrayListExtra(SPConstants.PHOTOS_KEY);
				if (photos != null && photos.size() > 0) {
					for (String photo : photos) {
						mediaFiles.add(photo);
					}
				}
			}
			break;
			case SPConstants.REQUEST_VIDEO: {
				Bundle cb = intent.getExtras();
				String mediapath = cb.getString("mediapath");
				mediaFiles.add(mediapath);
			}
			break;
			case SPConstants.REQUEST_VOICE: {
				Bundle cb = intent.getExtras();
				String mediapath = cb.getString("mediapath");
				mediaFiles.add(mediapath);
			}
			break;
			case SPConstants.REQUEST_OTHER: {
				ArrayList<String> photos = intent.getStringArrayListExtra("mediapaths");
				if (photos != null && photos.size() > 0) {
					for (String photo : photos) {
						mediaFiles.add(photo);
					}
				}
			}
			break;
		}
		return mediaFiles;
	}

	/**
	 * 申请权限
	 * @param t
	 * @param permission
	 * @param requestCode
	 */
	public static <T> void requestPermissions(T t, String permission, int requestCode) {
		if (t instanceof  Activity) {
			ActivityCompat.requestPermissions((Activity) t, new String[]{ permission }, requestCode);
		} else if (t instanceof Fragment) {
			if (Build.VERSION.SDK_INT >= 23) {
				((Fragment) t).requestPermissions(new String[]{ permission }, requestCode);
			} else {
				FragmentCompat.requestPermissions((Fragment) t, new String[]{ permission }, requestCode);
			}
		}
	}

	/**
	 * 判断是否有某权限
	 * @param context
	 * @param permission
	 * @return
	 */
	public static boolean checkSelfPermission(Context context, String permission) {
		final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
		if (Build.VERSION.SDK_INT >= 23) {
			if (targetSdkVersion >= 23) {
				return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
			} else {
				return PermissionChecker.checkSelfPermission(context, permission) == PermissionChecker.PERMISSION_GRANTED;
			}
		} else {
			return new PackageManagerWrapper(context).hasPermission(permission);
		}
	}

	/**
	 * 生成二维码Bitmap
	 *
	 * @param content   内容
	 * @param widthPix  图片宽度
	 * @param heightPix 图片高度
	 * @param logoBm    二维码中心的Logo图标（可以为null）
	 * @param filePath  用于存储二维码图片的文件路径
	 * @return 生成的二维码
	 */
	public static Bitmap createQRImage(String content, int widthPix, int heightPix, Bitmap logoBm, String filePath) {
		try {
			if (content == null || "".equals(content)) {
				return null;
			}

			//配置参数
			Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			//容错级别
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			//设置空白边距的宽度
			//hints.put(EncodeHintType.MARGIN, 2); //default is 4

			// 图像数据转换，使用了矩阵转换
			BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);
			int[] pixels = new int[widthPix * heightPix];
			// 下面这里按照二维码的算法，逐个生成二维码的图片，
			// 两个for循环是图片横列扫描的结果
			for (int y = 0; y < heightPix; y++) {
				for (int x = 0; x < widthPix; x++) {
					if (bitMatrix.get(x, y)) {
						pixels[y * widthPix + x] = 0xff000000;
					} else {
						pixels[y * widthPix + x] = 0xffffffff;
					}
				}
			}

			// 生成二维码图片的格式，使用ARGB_8888
			Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
			bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);

			if (logoBm != null) {
				bitmap = addLogo(bitmap, logoBm, -1);
			}

			//必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的，内存消耗巨大！
			if (bitmap != null) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));
			}
			return bitmap;
		} catch (WriterException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 向一张图片中间添加logo小图片(图片合成)
	 *
	 * @param srcBitmap 原图片
	 * @param logoBitmap logo图片
	 * @param logoPercent 百分比 (用于调整logo图片在原图片中的显示大小, 取值范围[0,1], 传值不合法时使用0.2F)
	 *                    原图片是二维码时,建议使用0.2F,百分比过大可能导致二维码扫描失败。
	 * @return
	 */
	@Nullable
	private static Bitmap addLogo(@Nullable Bitmap srcBitmap, @Nullable Bitmap logoBitmap, float logoPercent){

		/** 1. 参数合法性判断 */
		if(srcBitmap == null){
			return null;
		}

		if(logoBitmap == null){
			return srcBitmap;
		}

		if(logoPercent < 0F || logoPercent > 1F){
			logoPercent = 0.2F;
		}

		/** 2. 获取原图片和Logo图片各自的宽、高值 */
		int srcWidth = srcBitmap.getWidth();
		int srcHeight = srcBitmap.getHeight();
		int logoWidth = logoBitmap.getWidth();
		int logoHeight = logoBitmap.getHeight();

		/** 3. 计算画布缩放的宽高比 */
		float scaleWidth = srcWidth * logoPercent / logoWidth;
		float scaleHeight = srcHeight * logoPercent / logoHeight;

		/** 4. 使用Canvas绘制,合成图片 */
		Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(srcBitmap, 0, 0, null);
		canvas.scale(scaleWidth, scaleHeight, srcWidth/2, srcHeight/2);
		canvas.drawBitmap(logoBitmap, srcWidth/2 - logoWidth/2, srcHeight/2 - logoHeight/2, null);

		return bitmap;
	}

}
